package book.demo;

import java.util.concurrent.atomic.AtomicReference;

/**
 * 可重入的自旋锁实现
 * @author：涂有
 * @date 2017年12月4日 下午2:54:51
 */
public class SpinLock {

	private AtomicReference<Thread> owner = new AtomicReference<>();
	private int count = 0;
	
	public void lock(){
		Thread current = Thread.currentThread();
		if(current == owner.get()){
			count++;
		}else{
			while(!owner.compareAndSet(null, current));
		}
	}
	
	public void unlock(){
		Thread current = Thread.currentThread();
		if(current == owner.get()){
			if(count > 0){
				count--;
			}else{
				while(!owner.compareAndSet(current, null));
			}
		}
	}
	
	public static void main(String[] args) {
		
		SpinLock lock = new SpinLock();
		Thread t1 = new Thread(){
			@Override
			public void run() {
				lock.lock();
				try{
					System.out.println("线程1第一次锁");
					lock.lock();
					try{
						System.out.println("线程1第二次锁");
					}finally {
						lock.unlock();
					}
				}finally{
					lock.unlock();
				}
			}
		};
		Thread t2 = new Thread(){
			@Override
			public void run() {
				lock.lock();
				try{
					System.out.println("线程2第一次锁");
					lock.lock();
					try{
						System.out.println("线程2第二次锁");
					}finally {
						lock.unlock();
					}
				}finally{
					lock.unlock();
				}
			}
		};
		t2.start();
		t1.start();
	}
}
